<?php

namespace App\Http\Model\RoomBackgroundPicture;

use App\Http\Model\Base;
use App\Http\Model\Room;
use Illuminate\Support\Facades\Redis;

class BackgroundPictureManagement extends Base
{
    //type
    const TYPE_OF_CBD_AND_SMALL_ROOM = 1;//cbd和小屋
    const TYPE_OF_CBD_ONLY = 2;//仅cbd
    const TYPE_OF_SMALL_ROOM_ONLY = 3;//仅小屋
    const TYPE_OF_SPECIAL_CBD = 4;//指定cbd/小屋可见

    //is_show
    const IS_SHOW_YES = 1;//展示
    const IS_SHOW_NO = 0;//不展示

    /**
     * 表名字
     * @var string
     */
    protected $table = 'room_background_picture_management';

    //redis缓存key
    const REDIS_KEY = "RoomBackgroundPictureManagement:%s";
    const REDIS_EXPIRE = 86400 * 30; //生存期


    /**
     * 指示模型是否自动维护时间戳
     *
     * @var bool
     */
    public $timestamps = true;

    /**
     * 模型日期列的存储格式。
     *
     * @var string
     */
    protected $dateFormat = 'U';

    /**
     * 可以被批量赋值的属性。
     *
     * @var array
     */
    protected $fillable = ['id', 'type', 'is_show', 'weight', 'resource_url', 'resource_url2', 'start_time', 'end_time', 'created_at', 'updated_at'];

    /**
     * 构造函数
     * @param array $attributes
     */
    public function __construct(array $attributes = [])
    {
        parent::__construct($this->table, $attributes);
    }

    /**
     * 获取展示位置
     *
     * Created at 2021/11/12 11:47
     * @Author <yuxiang.zhu@asiainnovations.net>
     * @return array[]
     */
    public static function getTypes(): array
    {
        return [
            ['id' => 1, 'value' => 'CBD & 小屋'],
            ['id' => 2, 'value' => '仅CBD'],
            ['id' => 3, 'value' => '仅小屋'],
            ['id' => 4, 'value' => '指定CBD可见'],
        ];
    }

    /**
     * Created at 2021/11/12 12:01
     * @Author <yuxiang.zhu@asiainnovations.net>
     * @return int[]
     */
    public static function getIsShowStatus(): array
    {
        return [self::IS_SHOW_YES, self::IS_SHOW_NO];
    }

    /**
     * 获取小屋背景墙资源
     *
     * Created at 2021/11/15 09:40
     * @Author <yuxiang.zhu@asiainnovations.net>
     * @return array
     */
    private static function getSmallRoomResources(): array
    {
        $where = 'is_show=' . (self::IS_SHOW_YES)
            . ' and type in(' . implode(',', [self::TYPE_OF_SMALL_ROOM_ONLY, self::TYPE_OF_CBD_AND_SMALL_ROOM]) . ')';
        return self::query()->whereRaw($where)->get()->toArray();
    }

    /**
     * 获取CBD背景墙资源
     *
     * Created at 2021/11/15 09:41
     * @Author <yuxiang.zhu@asiainnovations.net>
     * @return array
     */
    private static function getCBDRoomResources(): array
    {
        $where = 'is_show=' . (self::IS_SHOW_YES)
            . ' and type in(' . implode(',', [self::TYPE_OF_CBD_AND_SMALL_ROOM, self::TYPE_OF_CBD_ONLY]) . ')';
        return self::query()->whereRaw($where)->get()->toArray();
    }

    /**
     * 获取指定CBD背景墙资源
     *
     * Created at 2021/11/15 09:45
     * @Author <yuxiang.zhu@asiainnovations.net>
     * @param string $roomUuId
     * @return array
     */
    private static function getSpecialCBDRoomResources(string $roomUuId): array
    {
        $managementIds = BackgroundPictureSpecial::query()->where(['room_uid' => $roomUuId])
            ->pluck('management_id')->toArray();
        return self::query()->whereIn('id', $managementIds)->where('is_show', self::IS_SHOW_YES)
            ->get()->toArray();
    }

    /**
     * 查询房间背景墙
     *
     * Created at 2021/11/15 09:52
     * @Author <yuxiang.zhu@asiainnovations.net>
     * @param int $roomId
     * @return array
     */
    public static function getRoomResources(int $roomId): array
    {
        $roomInfo = (new Room())->get_room($roomId);
        if (!$roomInfo) {
            return [];
        }

        $businessType = $roomInfo['business_type'];//房间 类型
        $list = [];
        if ($businessType == 0) {//小屋
            $list = self::getSmallRoomResources();
        } elseif ($businessType == 1) {//cbd
            $list = array_merge(self::getCBDRoomResources(), self::getSpecialCBDRoomResources($roomInfo['room_uid']));
        }

        if ($list) {
            //去掉不在时间范围内的资源
            $time = time();
            foreach ($list as $k => $d){
                if(!empty($d['start_time']) && !empty($d['end_time'])){
                    if($time < $d['start_time'] || $time > $d['end_time']){
                        unset($list[$k]);
                    }
                }
            }
            $list = array_merge($list);

            $weights = array_column($list,'weight');//权重
            array_multisort($weights,SORT_DESC, $list);
        }

        return $list;
    }

    /**
     * 删除缓存
     * @param int $resourceUrl 图片地址
     */
    public static function clearPictureCache($resourceUrl)
    {
        if (empty($resourceUrl)) {
            return;
        }
        $filename = basename($resourceUrl);
        $redisKey = sprintf(self::REDIS_KEY, $filename);
        Redis::del($redisKey);
    }

    /**
     * 检查图片的有效期
     * @param string $filepath 图片地址
     * @return bool true正常 false已过期
     */
    public static function checkPictureExpire($filepath)
    {
        if (empty($filepath)) {
            return false;
        }
        $filenameArr = explode("!", basename($filepath));
        $filename = $filenameArr[0];

        $redisKey = sprintf(self::REDIS_KEY, $filename);

        $cache = Redis::get($redisKey);
        $time = time();
        if ($cache) {
            $cache = json_decode($cache, 1);
            if (empty($cache['start_time']) || empty($cache['end_time'])) {
                return true;
            } elseif ($time < $cache['start_time'] || $time > $cache['end_time']) {
                return false;
            }
        } else {
            $where[] = ['is_show', '=', 1];
            $where[] = ['resource_url', 'like', "%$filename"];
            $where[] = ['resource_url2', 'like', "%$filename"];
            $vo = self::query()->where($where)->first();
            $expire = self::REDIS_EXPIRE;
            if ($vo) {
                if (!empty($vo->end_time)) {
                    //如果有失效时间，则设置生存期为失效时间
                    $time = $vo->end_time - time();
                    $expire = $time <= 0 ? $expire : $time;
                }
            } else {
                $vo = ['id' => 0]; //写入一条无意义的数据
            }
            Redis::setex($redisKey, $expire, json_encode($vo));

            //检查有效期
            if ($vo) {
                if (empty($vo->start_time) || empty($vo->end_time)) {
                    return true;
                } elseif ($time < $vo->start_time || $time > $vo->end_time) {
                    return false;
                }
            }

        }
        return true;
    }
}